package com.gs.netty.client.handler;


import com.gs.netty.client.exception.WebSocketClientHandshakerException;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.*;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * WebSocket 客户端同步握手处理器。作用于，客户端连接服务端成功了，但是还没有进行 ws 握手协议。
 */

public class WebSocketClientSynchronizedHandshaker extends ChannelInboundHandlerAdapter {

    private  WebSocketClientHandshaker webSocketClientHandshaker;

    private final long handshakeTimeoutMillis;

    private Semaphore semaphore = new Semaphore(0);

    public WebSocketClientSynchronizedHandshaker(WebSocketClientHandshaker webSocketClientHandshaker, long handshakeTimeoutMillis) {
        this.webSocketClientHandshaker = webSocketClientHandshaker;
        this.handshakeTimeoutMillis =handshakeTimeoutMillis;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        // 证明是握手响应事件
        if (evt instanceof WebSocketClientProtocolHandler.ClientHandshakeStateEvent

        && WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HANDSHAKE_COMPLETE == evt
        ) {

            // 移除该处理器，因为握手成功了，这个处理器就没有什么用了
            // TODO 开启一个任务去拉取接口权重消息，客户端好进行负载均衡

            // 证明是握手成功了，唤醒阻塞线程
            semaphore.release();
            ctx.pipeline().remove(this);
        }else {
            ctx.fireUserEventTriggered(evt);
        }
    }

    public boolean isSynchronizedHandshakeComplete() throws WebSocketClientHandshakerException {

        try {
            // 握手
            return webSocketClientHandshaker.isHandshakeComplete() ||
                    (semaphore.tryAcquire(handshakeTimeoutMillis, TimeUnit.MILLISECONDS) || webSocketClientHandshaker.isHandshakeComplete());
        } catch (InterruptedException e) {
            throw new WebSocketClientHandshakerException(e);
        }
    }
}
